<!DOCTYPE html>
<html th:lang="${#locale.toString()}"
	th:lang-direction="#{language.direction}"
	xmlns:th="http://www.thymeleaf.org">

<th:block
	th:insert="~{fragments/common :: head(title=#{adjustContrast.title})}"></th:block>


<body>
	<div id="page-container">
		<div id="content-wrap">
			<div th:insert="~{fragments/navbar.html :: navbar}"></div>
			<br> <br>
			<div class="container">
				<div class="row justify-content-center">
					<div class="col-md-12">
                        <div class="row justify-content-center">
                            <div class="col-md-3">
                                <div id="sliders-container" style="display:none;">
                                    <h4>
                                        <span th:text="#{adjustContrast.contrast}"></span> <span id="contrast-val">100</span>%
                                    </h4>
                                    <input type="range" min="0" max="200" value="100" id="contrast-slider" />

                                    <h4>
                                        <span th:text="#{adjustContrast.brightness}"></span> <span id="brightness-val">100</span>%
                                    </h4>
                                    <input type="range" min="0" max="200" value="100" id="brightness-slider" />

                                    <h4>
                                        <span th:text="#{adjustContrast.saturation}"></span> <span id="saturation-val">100</span>%
                                    </h4>
                                    <input type="range" min="0" max="200" value="100" id="saturation-slider" />
                                </div>
                            </div>
                            <div class="col-md-7">
                                <h2 th:text="#{adjustContrast.header}"></h2>
                                <div class="col-md-8">
                                    <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
                                </div>
                                <br>
                                <canvas id="contrast-pdf-canvas"></canvas>
                                <button id="download-button" class="btn btn-primary" th:text="#{adjustContrast.download}"></button>
                            </div>
                        </div>
                        <style>
                            #flex-container {
					            display: flex;
					            align-items: center;
					        }
					        #sliders-container {
					            padding: 0 20px;  /* Add some padding to separate sliders from canvas */
					        }
                        </style>


						<script src="pdfjs/pdf.js"></script>
						<script>
						  var canvas = document.getElementById('contrast-pdf-canvas');
						  var context = canvas.getContext('2d');
						  var originalImageData = null;
						  var allPages = [];
						  var pdfDoc = null;
						  var pdf = null; // This is the current PDF document
						
						  async function renderPDFAndSaveOriginalImageData(file) {
						    var fileReader = new FileReader();
						    fileReader.onload = async function() {
						      var data = new Uint8Array(this.result);
						      pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js'
						      pdf = await pdfjsLib.getDocument({data: data}).promise;
						
						      // Get the number of pages in the PDF
						      var numPages = pdf.numPages;
						      allPages = Array.from({length: numPages}, (_, i) => i + 1);
						      
						      // Create a new PDF document
						      pdfDoc = await PDFLib.PDFDocument.create();
						      // Render the first page in the viewer
						      await renderPageAndAdjustImageProperties(1);
						      document.getElementById("sliders-container").style.display = "block";
						      
						    };
						    fileReader.readAsArrayBuffer(file);
						  }
						
						  // This function is now async and returns a promise
						  function renderPageAndAdjustImageProperties(pageNum) {
						      return new Promise(async function(resolve, reject) {
						          var page = await pdf.getPage(pageNum);
						          var scale = 1.5;
						          var viewport = page.getViewport({ scale: scale });
						
						          canvas.height = viewport.height;
						          canvas.width = viewport.width;
						
						          var renderContext = {
						            canvasContext: context,
						            viewport: viewport
						          };
						
						          var renderTask = page.render(renderContext);
						          renderTask.promise.then(function () {
						            originalImageData = context.getImageData(0, 0, canvas.width, canvas.height);
						            adjustImageProperties();
						            resolve();
						          });
						          canvas.classList.add("fixed-shadow-canvas");
						      });
						  }
						  
						
						    function adjustImageProperties() {
						        var contrast = parseFloat(document.getElementById('contrast-slider').value);
						        var brightness = parseFloat(document.getElementById('brightness-slider').value);
						        var saturation = parseFloat(document.getElementById('saturation-slider').value);
						
						        contrast /= 100; // normalize to range [0, 2]
						        brightness /= 100; // normalize to range [0, 2]
						        saturation /= 100; // normalize to range [0, 2]
						
						        if (originalImageData) {
						          var newImageData = context.createImageData(originalImageData.width, originalImageData.height);
						          newImageData.data.set(originalImageData.data);
						
						          for(var i=0; i<newImageData.data.length; i+=4)
						          {
						            var r = newImageData.data[i];
						            var g = newImageData.data[i+1];
						            var b = newImageData.data[i+2];
						            // Adjust contrast
						            r = adjustContrastForPixel(r, contrast);
						            g = adjustContrastForPixel(g, contrast);
						            b = adjustContrastForPixel(b, contrast);
						            // Adjust brightness
						            r = adjustBrightnessForPixel(r, brightness);
						            g = adjustBrightnessForPixel(g, brightness);
						            b = adjustBrightnessForPixel(b, brightness);
						            // Adjust saturation
						            var rgb = adjustSaturationForPixel(r, g, b, saturation);
						            newImageData.data[i] = rgb[0];
						            newImageData.data[i+1] = rgb[1];
						            newImageData.data[i+2] = rgb[2];
						          }
						
						          context.putImageData(newImageData, 0, 0);
						        }
						      }
						
						    function rgbToHsl(r, g, b) {
						        r /= 255, g /= 255, b /= 255;
						
						        var max = Math.max(r, g, b), min = Math.min(r, g, b);
						        var h, s, l = (max + min) / 2;
						
						        if (max === min) {
						          h = s = 0; // achromatic
						        } else {
						          var d = max - min;
						          s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
						
						          switch (max) {
						            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
						            case g: h = (b - r) / d + 2; break;
						            case b: h = (r - g) / d + 4; break;
						          }
						
						          h /= 6;
						        }
						
						        return [h, s, l];
						      }
						
						      function hslToRgb(h, s, l) {
						        var r, g, b;
						
						        if (s === 0) {
						          r = g = b = l; // achromatic
						        } else {
						          var hue2rgb = function hue2rgb(p, q, t) {
						            if (t < 0) t += 1;
						            if (t > 1) t -= 1;
						            if (t < 1 / 6) return p + (q - p) * 6 * t;
						            if (t < 1 / 2) return q;
						            if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
						            return p;
						          };
						
						          var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
						          var p = 2 * l - q;
						
						          r = hue2rgb(p, q, h + 1 / 3);
						          g = hue2rgb(p, q, h);
						          b = hue2rgb(p, q, h - 1 / 3);
						        }
						
						        return [r * 255, g * 255, b * 255];
						      }
						      
						      function adjustContrastForPixel(pixel, contrast) {
						          // Normalize to range [-0.5, 0.5]
						          var normalized = pixel / 255 - 0.5;
						
						          // Apply contrast
						          normalized *= contrast;
						
						          // Denormalize back to [0, 255]
						          return (normalized + 0.5) * 255;
						        }
						      function clamp(value, min, max) {
						    	  return Math.min(Math.max(value, min), max);
						    	}
						
						      function adjustSaturationForPixel(r, g, b, saturation) {
						          var hsl = rgbToHsl(r, g, b);
						          
						          // Adjust saturation
						          hsl[1] = clamp(hsl[1] * saturation, 0, 1);
						
						          // Convert back to RGB
						          var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
						
						          // Return adjusted RGB values
						          return rgb;
						        }
						      
						      function adjustBrightnessForPixel(pixel, brightness) {
						          return Math.max(0, Math.min(255, pixel * brightness));
						        }  
						      
						      async function downloadPDF() {
						    	  for (var i = 0; i < allPages.length; i++) {
						    	    await renderPageAndAdjustImageProperties(allPages[i]);
						    	    const pngImageBytes = canvas.toDataURL('image/png');
						    	    const pngImage = await pdfDoc.embedPng(pngImageBytes);
						    	    const pngDims = pngImage.scale(1);
						
						    	    // Create a blank page matching the dimensions of the image
						    	    const page = pdfDoc.addPage([pngDims.width, pngDims.height]);
						
						    	    // Draw the PNG image
						    	    page.drawImage(pngImage, {
						    	      x: 0,
						    	      y: 0,
						    	      width: pngDims.width,
						    	      height: pngDims.height
						    	    });
						    	  }
						
						    	  // Serialize the PDFDocument to bytes (a Uint8Array)
						    	  const pdfBytes = await pdfDoc.save();
						    	  
						    	  // Create a Blob
						    	  const blob = new Blob([pdfBytes.buffer], {type: "application/pdf"});
						    	  
						    	  // Create download link
						    	  const downloadLink = document.createElement('a');
						    	  downloadLink.href = URL.createObjectURL(blob);
						    	  downloadLink.download = "download.pdf";
						    	  downloadLink.click();
						    	  
						   		// After download, reset the viewer and clear stored data
						    	  allPages = [];  // Clear the pages
						    	  originalImageData = null;  // Clear the image data
						
						    	  // Go back to page 1 and render it in the viewer
						    	  if (pdf !== null) {
						    	    renderPageAndAdjustImageProperties(1);
						    	  }
						    	  
						    	}
						
						      
						
						
						    // Event listeners
						    document.getElementById('fileInput-input').addEventListener('change', function(e) {
						      if (e.target.files.length > 0) {
						        renderPDFAndSaveOriginalImageData(e.target.files[0]);
						      }
						    });
						
						    document.getElementById('contrast-slider').addEventListener('input', function() {
						      document.getElementById('contrast-val').textContent = this.value;
						      adjustImageProperties();
						    });
						
						    document.getElementById('brightness-slider').addEventListener('input', function() {
						      document.getElementById('brightness-val').textContent = this.value;
						      adjustImageProperties();
						    });
						
						    document.getElementById('saturation-slider').addEventListener('input', function() {
						      document.getElementById('saturation-val').textContent = this.value;
						      adjustImageProperties();
						    });
						
						    document.getElementById('download-button').addEventListener('click', function() {
						        downloadPDF();
						      });
						  </script>
					</div>
				</div>
			</div>
		</div>
		<div th:insert="~{fragments/footer.html :: footer}"></div>
	</div>
</body>
</html>
